package web.directories.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import common.IOHelper;
import domain.entities.*;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.springframework.beans.factory.annotation.Autowired;
import services.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: nico
 * Date: 22/08/12
 * Time: 12:52
 * To change this template use File | Settings | File Templates.
 */
@Namespace("/Directories/Team")
public class InvestigatorController extends ActionSupport implements ModelDriven, ServletResponseAware, ServletRequestAware {

    private InvestigatorCRUDService investigatorService;
    private CentroCRUDService centroService;
    private CompromisoPaisService paisService;
    private RoleCRUDService roleCRUDService;
    private Involucrado involucrado = new Involucrado();
    private int editableInvolucradoId;
    private int centroId;
    private int siteId;
    private List<Compromisopais> paisList;
    private List<Involucrado> list;
    private List<Centro> sites;
    private List<Role> roles;
    private List<Specialty> specialities;
    private LinkedHashMap<TherapeuticArea, ArrayList<Specialty>> languageMap;
    private TherapeuticAreaCRUDService therapeuticAreaCRUDService;
    private SpecialityCRUDService specialityCRUDService;
    private String nameOrSurname;
    private String indexForInvestigators;
    private List<DoctorDegree> degrees;
    private DoctorDegreeService doctorDegreeService;

    private File data;
    private String dataContentType;
    private String dataFileName;

    private File dataEnglish;
    private String dataContentTypeEnglish;
    private String dataEnglishFileName;

    private String errorMessage;

    @Autowired
    public InvestigatorController(InvestigatorCRUDService investigatorService, CentroCRUDService centroService, RoleCRUDService roleCRUDService, TherapeuticAreaCRUDService therapeuticAreaCRUDService, SpecialityCRUDService specialityCRUDService, DoctorDegreeService doctorDegreeService, CompromisoPaisService paisService) {
        this.investigatorService = investigatorService;
        this.centroService = centroService;
        this.roleCRUDService = roleCRUDService;
        this.therapeuticAreaCRUDService = therapeuticAreaCRUDService;
        this.specialityCRUDService = specialityCRUDService;
        this.doctorDegreeService = doctorDegreeService;
        this.paisService = paisService;
        degrees =  doctorDegreeService.findAll();
        DoctorDegree d = new DoctorDegree( -2, "Other");
        degrees.add(d);
        paisList = paisService.findAll();

        list = new ArrayList<Involucrado>(0);
        sites = centroService.findAllSites();
        roles = roleCRUDService.findSiteRole();

        prepareAreaAndSpecialities();
    }

    @Action(value="main", results={
            @Result(name="success",location="/directories.investigator.tiles", type="tiles")
    })
    public String execute(){
        return SUCCESS;
    }

    @Action(value="list", results={
            @Result(name="success",location="/directories.investigator.tiles", type="tiles")
    })
    public String list(){
        if(involucrado.getTherapeuticArea() != null)
            involucrado.setTherapeuticArea(therapeuticAreaCRUDService.findById(involucrado.getTherapeuticArea().getId()));
        if(involucrado.getSpeciality() != null)
            involucrado.setSpeciality(specialityCRUDService.findById(involucrado.getSpeciality().getId()));
        if(involucrado.getCentro() != null){
            involucrado.setCentro(centroService.findById(involucrado.getCentro().getId()));
        }
        CriteriaInvestigator cr = new CriteriaInvestigator(involucrado);
        list = investigatorService.list(cr);
        for(Involucrado i : list){
          /*  if(i.getDegree() == null || i.getDegree().isEmpty())
                i.setDegree("-");*/
            if(i.getPhone() == null || i.getPhone().isEmpty())
                i.setPhone("-");
            if(i.getMobilePhone() == null || i.getMobilePhone().isEmpty())
                i.setMobilePhone("-");
            if(i.getEmail() == null || i.getEmail().isEmpty())
                i.setEmail("-");
        }
        sites = centroService.findAllSites();
        roles = roleCRUDService.findSiteRole();

        prepareAreaAndSpecialities();

        return SUCCESS;
    }

    @Action(value="create", results={
            @Result(name="success",location="/directories.investigator.create.tiles", type="tiles")
    })
    public String createInvolucrado() {
        sites = centroService.findAllSites();
        roles = roleCRUDService.findSiteRole();
        prepareAreaAndSpecialities();
        involucrado = null;
        return SUCCESS;
    }

    @Action(value="edit", results={
            @Result(name="success",location="/directories.investigator.create.tiles", type="tiles")
    })
    public String editInvolucrado() {
        sites = centroService.findAllSites();
        roles = roleCRUDService.findSiteRole();
        involucrado = investigatorService.getById(editableInvolucradoId);
        if(involucrado.getTherapeuticArea() == null){
            TherapeuticArea t = new TherapeuticArea();
            t.setId(-1);
            involucrado.setTherapeuticArea(t);
        }
        prepareAreaAndSpecialities();

        return SUCCESS;
    }

    @Action(value="save", results={
            @Result(name="success",location="main", type="redirectAction"),
            @Result(name="error",location="/directories.investigator.create.tiles", type="tiles")
    })
    public String saveInvolucrado() throws IOException {
        boolean existe = false;
        if(!involucrado.getCuit().equals("")){
            if(!investigatorService.findByCuit(involucrado.getCuit()).isEmpty()){
                errorMessage = "A member with CUIT/CUIL " + involucrado.getCuit() + " already exists.";
                return ERROR;
            }
        }
        else if(!involucrado.getCnpj().equals("")){
            if(!investigatorService.findByCnpj(involucrado.getCnpj()).isEmpty()){
                errorMessage = "A member with CNPJ " + involucrado.getCnpj() + " already exists.";
                return ERROR;
            }
        }
        else if(!involucrado.getRut().equals("")){
            if(!investigatorService.findByRut(involucrado.getRut()).isEmpty()){
                errorMessage = "A member with RUT " + involucrado.getRut() + " already exists.";
                return ERROR;
            }
        }
        else if(!involucrado.getNit().equals("")){
            if(!investigatorService.findByNit(involucrado.getNit()).isEmpty()){
                errorMessage = "A member with NIT " + involucrado.getNit() + " already exists.";
                return ERROR;
            }
        }

        if(involucrado.getTherapeuticArea().getId().intValue() == -1)
            involucrado.setTherapeuticArea(null);

        doctorDegreeService.checkType(involucrado.getDegree().getDescripcion());

        if( involucrado.getDegree().getId() !=null ){
            if( !involucrado.getDegree().getId().equals(-2) )
                involucrado.setDegree(doctorDegreeService.findbyId(involucrado.getDegree().getId()));
            else
                involucrado.setDegree(doctorDegreeService.findByDescripcion(involucrado.getDegree().getDescripcion()));
        }
        if(involucrado.getCompromisopais().getId() != null)
            involucrado.setCompromisopais(paisService.findById(involucrado.getCompromisopais().getId()));

        saveInvolucradoCVs();

        investigatorService.save(involucrado);
        return SUCCESS;
    }

    private void saveInvolucradoCVs() throws IOException {
        IOHelper ioh = new IOHelper();

        if(data != null ){
            involucrado.setFile(ioh.convertFileToBytes(data));
            involucrado.setFilename(dataFileName);
        }else if( involucrado.getId() != null ){
            Involucrado inv =   investigatorService.getById(involucrado.getId());
            involucrado.setFile(inv.getFile());
            involucrado.setFilename(inv.getFilename());
        }

        if(dataEnglish != null ){
            involucrado.setFileEnglish(ioh.convertFileToBytes(dataEnglish));
            involucrado.setFilenameEnglish(dataEnglishFileName);
        }else if( involucrado.getId() != null ){
            Involucrado inv =   investigatorService.getById(involucrado.getId());
            involucrado.setFileEnglish(inv.getFileEnglish());
            involucrado.setFilenameEnglish(dataEnglishFileName);
        }

    }

    @Action(value="downloadFile", results={
            @Result(name="success",location="/directories.investigator.create.tiles", type="tiles")
    })
    public String downloadFile() throws IOException {

        if( involucrado.getId() != null && involucrado.getId() != 0){
            Involucrado inv =   investigatorService.getById(involucrado.getId());
            downloadFile(inv.getFile(),inv.getFilename());
        }
        return SUCCESS;
    }

    @Action(value="downloadFileEnglish", results={
            @Result(name="success",location="/directories.investigator.create.tiles", type="tiles")
    })
    public String downloadFileEnglish() throws IOException {

        if( involucrado.getId() != null && involucrado.getId() != 0){
            Involucrado inv =   investigatorService.getById(involucrado.getId());
            downloadFile(inv.getFileEnglish(),inv.getFilenameEnglish());
        }
        return SUCCESS;
    }

    private void downloadFile(byte[] file, String filename) throws IOException {
            if( file != null){
                String[] ext = filename.split("\\.");
                // Initialize response.
                response.reset();
                if( ext[1].equals("pdf"))
                    response.setContentType("application/pdf");
                else
                    response.setContentType("application/doc");
                response.setHeader("Content-disposition", "attachment; filename=\""+filename+"\"");
                // Write file to response.
                OutputStream output = response.getOutputStream();
                output.write(file);
                output.close();
            }
    }

    @Action(value="delete", results={
            @Result(name="success",location="main", type="redirectAction")
    })
    public String deleteInvolucrado() {
        investigatorService.delete(involucrado);
        return SUCCESS;
    }

    @Action(value="getInvolucradosByNameSurname", results={
            @Result(name="success",location="/WEB-INF/jsp/Protocols/investigator/involucradosWindow.jsp")
    })
    public String getInvolucradosByNameSurname() {
        list = investigatorService.findByNameOrSurname(nameOrSurname);
        return SUCCESS;
    }

    @Action(value="getInvestigatorsByNameSurname", results={
            @Result(name="success",location="/WEB-INF/jsp/Protocols/investigator/investigatorsWindow.jsp")
    })
    public String getInvestigatorsByNameSurname() {
        list = investigatorService.findByNameOrSurname(nameOrSurname);
        indexForInvestigators = "0";
        return SUCCESS;
    }

    @Action(value="getInvestigatorsSIByNameSurname", results={
            @Result(name="success",location="/WEB-INF/jsp/Protocols/investigator/investigatorsWindow.jsp")
    })
    public String getInvestigatorsSIByNameSurname() {
        list = investigatorService.findByNameOrSurname(nameOrSurname);
        indexForInvestigators = "1";
        return SUCCESS;
    }

    @Action(value="getInvestigatorsSIByNameSurname1", results={
            @Result(name="success",location="/WEB-INF/jsp/Directories/cda/investigatorList.jsp")
    })
    public String getInvestigatorsSIByNameSurname1() {
        list = investigatorService.findByNameOrSurname(nameOrSurname);
        return SUCCESS;
    }

    public Involucrado getInvolucrado() {
        return involucrado;
    }

    public void setInvolucrado(Involucrado involucrado) {
        this.involucrado = involucrado;
    }

    public int getEditableInvolucradoId() {
        return editableInvolucradoId;
    }

    public void setEditableInvolucradoId(int editableInvolucradoId) {
        this.editableInvolucradoId = editableInvolucradoId;
    }

    public List<Involucrado> getList() {
        return list;
    }

    public void setList(List<Involucrado> list) {
        this.list = list;
    }

    public List<Centro> getSites() {
        return sites;
    }

    public void setSites(List<Centro> sites) {
        this.sites = sites;
    }

    public int getSiteId() {
        return siteId;
    }

    public void setSiteId(int siteId) {
        this.siteId = siteId;
    }


    public int getCentroId() {
        return centroId;
    }

    public void setCentroId(int centroId) {
        this.centroId = centroId;
    }

    @Override
    public Object getModel() {
        return this.involucrado;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public LinkedHashMap<TherapeuticArea, ArrayList<Specialty>> getLanguageMap() {
        return languageMap;
    }

    public void setLanguageMap(LinkedHashMap<TherapeuticArea, ArrayList<Specialty>> languageMap) {
        this.languageMap = languageMap;
    }

    public List<Specialty> getSpecialities() {
        return specialities;
    }

    public void setSpecialities(List<Specialty> specialities) {
        this.specialities = specialities;
    }

    private void prepareAreaAndSpecialities(){
        ArrayList<TherapeuticArea> therapeuticAreas = new ArrayList<TherapeuticArea>(therapeuticAreaCRUDService.list());
        languageMap = new LinkedHashMap<TherapeuticArea, ArrayList<Specialty>>();
        specialities = new ArrayList<Specialty>(0);

        for(TherapeuticArea t : therapeuticAreas){
            specialities.addAll(t.getSpecialities());
        }
        TherapeuticArea t = new TherapeuticArea();
        t.setId(-1);
        t.setName("Choose an Area");
        t.setSpecialities(specialities);

        languageMap.put(t, new ArrayList<Specialty>(t.getSpecialities()));
        for(TherapeuticArea t2 : therapeuticAreas){
            languageMap.put(t2, new ArrayList<Specialty>(t2.getSpecialities()));
        }

    }

    public String getNameOrSurname() {
        return nameOrSurname;
    }

    public void setNameOrSurname(String nameOrSurname) {
        this.nameOrSurname = nameOrSurname;
    }

    public String getIndexForInvestigators() {
        return indexForInvestigators;
    }

    public void setIndexForInvestigators(String indexForInvestigators) {
        this.indexForInvestigators = indexForInvestigators;
    }

    public List<DoctorDegree> getDegrees() {
        return degrees;
    }

    public File getData() {
        return data;
    }

    public void setDegrees(List<DoctorDegree> degrees) {
        this.degrees = degrees;
    }

    public void setData(File data) {
        this.data = data;
    }

    public String getDataContentType() {
        return dataContentType;
    }

    public void setDataContentType(String dataContentType) {
        this.dataContentType = dataContentType;
    }

    public String getDataFileName() {
        return dataFileName;
    }

    public void setDataFileName(String dataFileName) {
        this.dataFileName = dataFileName;
    }

    public List<Compromisopais> getPaisList() {
        return paisList;
    }

    public void setPaisList(List<Compromisopais> paisList) {
        this.paisList = paisList;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    private HttpServletRequest request;
    private HttpServletResponse response;

    @Override
    public void setServletRequest(javax.servlet.http.HttpServletRequest request) {
        this.request   = request;
    }

    @Override
    public void setServletResponse(javax.servlet.http.HttpServletResponse response) {
        this.response = response;
    }

    public File getDataEnglish() {
        return dataEnglish;
    }

    public void setDataEnglish(File dataEnglish) {
        this.dataEnglish = dataEnglish;
    }

    public String getDataContentTypeEnglish() {
        return dataContentTypeEnglish;
    }

    public void setDataContentTypeEnglish(String dataContentTypeEnglish) {
        this.dataContentTypeEnglish = dataContentTypeEnglish;
    }

    public String getDataEnglishFileName() {
        return dataEnglishFileName;
    }

    public void setDataEnglishFileName(String dataEnglishFileName) {
        this.dataEnglishFileName = dataEnglishFileName;
    }
}
